/**
 * SessionContext.java 
 * Copyright © 2015-3015, 杭州泊享网络科技有限公司
 * 
 * @author Liu Tao
 * @create 2013年8月9日
 */
package com.pshare.framework.context;

import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang3.StringUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import com.pshare.session.Session;
import com.pshare.session.SessionFactory;
import com.pshare.session.Trackable;
import com.pshare.util.CookieUtil;

public class SessionContext {

	private static final String CACHE_USER_SESSIONID = "sessionId";
	private static final String APPSESSION_ATTR_ACCOUNT_ID = "userid";

//	private static ThreadLocal<Session> threadSession = new ThreadLocal<Session>();

	private static SessionFactory appSessionFactory;

	static {
		appSessionFactory = SpringContextHolder.getBean("appSessionFactory");
	}

	public static Session getSession() {
		HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes())
				.getRequest();
		return getSession(request);
	}

	public static Session getSession(HttpServletRequest request) {
//		Session s = (Session) threadSession.get();
//		String sessionId = getToken(request);
//		if (s == null || StringUtils.isBlank(sessionId) || !s.getId().equals(sessionId)) {
//			s = getSessionFromCache(sessionId);
//			threadSession.set(s);
//		}
//
//		return s;
		String sessionId = getToken(request);
		return getSession(sessionId);
	}

	public static Session getSession(String sessionId) {
//		Session s = (Session) threadSession.get();
//		if (s == null || StringUtils.isBlank(sessionId) || !s.getId().equals(sessionId)) {
//			s = getSessionFromCache(sessionId);
//			threadSession.set(s);
//		}
//		return s;
		return getSessionFromCache(sessionId);
	}

	public static Session getSessionFromCache(String sessionId) {
		return appSessionFactory.getSession(new Trackable() {
			public String getTrackId() {
				return sessionId;
			}
		});
	}

	/**
	 * 根据sessionId读取Session
	 * 
	 * @param sessionId
	 * @return Session
	 */
	public static Session getSessionByUserId(Long userId) {
		return userId == null ? null : getSession(getSessionIdByUserId(userId));
	}

	/**
	 * 根据userId读取sessionId
	 * 
	 * @param userId
	 * @return String
	 */
	public static String getSessionIdByUserId(Long userId) {
		return userId == null ? null : appSessionFactory.getSessionId(CACHE_USER_SESSIONID + userId);
	}

	public static Session readSession() {
		HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes())
				.getRequest();
//		Session s = (Session) threadSession.get();
		String sessionId = getToken(request);
		return readSession(sessionId);
	}

	/**
	 * 读取session，如果没有，就返回空值
	 * 
	 * @param sessionId
	 * @return Session
	 */
	public static Session readSession(String sessionId) {
		Session session = appSessionFactory.readSession(new Trackable() {
			public String getTrackId() {
				return sessionId;
			}
		});
		return session;
	}

	public static Session createSession() {
		return appSessionFactory.newSession();
	}

	public static void destroy(HttpServletRequest request) {
		String id = getToken(request);
		if (StringUtils.isBlank(id))
			return;
		destroy(id);
//		threadSession.remove();
	}

	/**
	 * @param sessioId
	 */
	public static void destroy(String sessionId) {
		if (StringUtils.isBlank(sessionId))
			return;
		Session session = getSessionFromCache(sessionId);
		if (session == null)
			return;

		Long userId = (Long) session.getAttribute(APPSESSION_ATTR_ACCOUNT_ID);
		if (userId != null) {
			appSessionFactory.removeSessionId(CACHE_USER_SESSIONID + userId);
		}

		session.destroy();
//		threadSession.remove();
	}

	/**
	 * @param userId
	 */
	public static void destroy(Long userId) {
		if (userId == null)
			return;
		String sessionIdKey = CACHE_USER_SESSIONID + userId;
		String sessionId = appSessionFactory.getSessionId(sessionIdKey);
		if (StringUtils.isBlank(sessionId))
			return;

		// 先销毁session
		Session session = getSessionFromCache(sessionId);
		session.destroy();
		// 再清空userId--sessionId记录
		appSessionFactory.removeSessionId(sessionIdKey);
//		threadSession.remove();
	}

	public static void fresh() {
//		if (threadSession.get() == null) {
//			return;
//		}
//		appSessionFactory.put(threadSession.get());
//		threadSession.remove();
	}

	// public static void restore(Session session) {
	// if (session != null) {
	// appSessionFactory.put(session);
	// }
	// }

	/**
	 * 
	 */
	public static void flush() {
		appSessionFactory.flush();
//		threadSession.remove();
	}

	/**
	 * 从请求对象中获取会话编号
	 *
	 * @param request
	 * @return String
	 */
	private static String getToken(HttpServletRequest request) {
		// 先尝试从参数中读取
		// String token = (String) request.getParameter(TOKEN_NAME);
		// if(StringUtils.isBlank(token)) {
		// 再尝试从cookie读取
		String token = CookieUtil.getToken(request);
		// }
		return token;
	}

	public static boolean setAttribute(String key, Object obj) {
		if (StringUtils.isBlank(key)) {
			return false;
		}

		Session session = SessionContext.getSession();
		session.setAttribute(key, obj);

		appSessionFactory.put(session);
		return true;
	}

	public static String setAttributes(Map<String, Object> map) {
		if (map == null || map.size() == 0) {
			return null;
		}
		Session session = SessionContext.getSession();
		for (String key : map.keySet()) {
			Object value = map.get(key);
			session.setAttribute(key, value);
		}

		appSessionFactory.put(session);
		return session.getId();
	}

}
